
Object.defineProperty(exports, "__esModule", { value: true });
/**
* @module packet
* @author: Hjava
* @description: 二进制数据操作类
* @since: 2018-07-16 11:33:45
*/
var byteBuffer_1 = __webpack_require__(/*! _util/byteBuffer */ "./src/core/utils/byteBuffer.ts");
var long_1 = __webpack_require__(/*! _util/long */ "./src/core/utils/long.ts");
var base64_1 = __webpack_require__(/*! _util/base64 */ "./src/core/utils/base64.ts");
var bufferType_1 = __webpack_require__(/*! _util/bufferType */ "./src/core/utils/bufferType.ts");
var apply_1 = __webpack_require__(/*! _util/apply */ "./src/core/utils/apply.ts");
var constant_1 = __webpack_require__(/*! _util/constant */ "./src/core/utils/constant.ts");
var log_1 = __webpack_require__(/*! ./../utils/log */ "./src/core/utils/log.ts");
var Packet = function (data) {
    if (data === void 0) { data = {}; }
    this.version = 1;
    this.bufferInited = false;
    this._capacity = constant_1.PACKAT_CONFIG.PROTO_PACKET_SIZE;
    this._position = constant_1.PACKAT_CONFIG.PACKET_HEAD_LENGTH;
    this.fromUnmarshall = false;
    this.init();
    apply_1.default(this, data);
    this.initAfter();
};
Packet.prototype = {
    appid: constant_1.APPID.DX,
    init: function () { },
    initAfter: function () { },
    initBuffer: function () {
        if (this.version > 1) {
            this._position = constant_1.PACKAT_CONFIG.PACKET_HEAD_LENGTH2;
        }
        this.buffer = new byteBuffer_1.default(this._capacity);
        this.buffer.position(this._position);
        return true;
    },
    release: function () {
        this.buffer = null;
    },
    setUri: function (uri) {
        this.uri = uri;
    },
    clear: function () {
    },
    copy: function () {
    },
    /**
     * @returns {ArrayBuffer}
     */
    snapshotBytes: function () {
        return this.buffer.snapshot ? this.buffer.snapshot : this.getBytes();
    },
    setUid: function (uid) { },
    /**
     * 获取字节流数组
     * @type {ArrayBuffer|*}
     */
    getBytes: function () {
        this._marshall();
        return this.buffer.getBytes();
    },
    /**
     * 获取字节流数组
     * @type {Array|*}
     */
    getArray: function () {
        this._marshall();
        return this.buffer.getArray();
    },
    __byteArr: [],
    serialize: function () {
        this.__byteArr = [];
        var arr = this.getArray();
        for (var i = 0; i < arr.length; i++) {
            this.__byteArr.push(arr[i]);
        }
        return JSON.stringify(this.__byteArr);
    },
    unserialize: function () {
        return this;
    },
    /**
     * 获取Base64字符串
     * @returns {*}
     */
    getBase64: function () {
        return base64_1.default.BAtob64(this.getArray());
    },
    /**
     * @return {ArrayBuffer}
     * @private
     */
    _marshall: function () {
        if (!this.bufferInited) {
            this.bufferInited = this.initBuffer();
        }
        /**
         * marshall customize packet
         */
        this.marshall();
        var length = this.buffer.position();
        this.buffer.putInt(length, 0);
        this.buffer.putInt(this.uri, 4);
        this.buffer.putShort(this.appid, 8);
        if (this.version > 1) {
            this.buffer.putShort(this.mversion, 10);
            this.buffer.putInt(this.crc32, 12);
            this.buffer.putInt(this.requestSeq, 16);
            this.buffer.putInt(this.extra, 20);
        }
    },
    /**
     * return pure object
     * @returns {MTDX.Message}
     */
    toPure: function () {
        delete this['_capacity'];
        delete this['_position'];
        delete this['buffer'];
        delete this['fromUnmarshall'];
        delete this['bufferInited'];
    },
    /**
     *
     * @param buffer {ByteBuffer}
     */
    parserFromBuffer: function (buffer) {
        this._unmarshall(buffer);
        return this;
    },
    /**
     * @param buffer {ByteBuffer}
     */
    fromBuffer: function (buffer) {
        this._unmarshall(buffer);
        return this;
    },
    /**
     *
     * @private
     */
    _unmarshall: function (buffer) {
        this.fromUnmarshall = true;
        this.buffer = byteBuffer_1.default.wrap(buffer);
        this.length = this.popInt();
        this.uri = this.popInt();
        this.appid = this.popShort();
        if (this.version > 1) {
            //
            this.mversion = this.popShort();
            this.crc32 = this.popInt();
            this.requestSeq = this.popInt();
            this.extra = this.popInt();
        }
        try {
            this.unmarshall();
        }
        catch (e) {
            log_1.default.error('Packet _unmarshall error info:' + e);
        }
    },
    /**
     * {boolean}
     * @param value{boolean}
     * @private
     */
    _pushBool: function (value) {
        this.buffer.writeByte(value ? 1 : 0);
    },
    popBool: function () {
        return this.popByte() == 1 ? true : false;
    },
    _pushByte: function (value) {
        this.buffer.writeByte(value);
    },
    popByte: function () {
        return this.buffer.readByte();
    },
    /**
     *  @param value{int}
     */
    _pushShort: function (value) {
        this.buffer.putShort(value);
    },
    /**
     *
     * @return {number}
     */
    popShort: function () {
        return this.buffer.popShort();
    },
    /**
     *
     * @param value{int}
     * @private
     */
    _pushInt: function (value) {
        this.buffer.putInt(value || 0);
    },
    /**
     *
     * @return {number}
     */
    popInt: function () {
        return this.buffer.popInt();
    },
    /**
     *
     * @param value
     * @private
     */
    _pushDouble: function (value) {
        this.buffer.putDouble(value || 0);
    },
    /**
     *
     * @return {number}
     */
    popDouble: function () {
        return this.buffer.popDouble();
    },
    /**
     *
     * @return {!Long}
     */
    popLong: function () {
        return this.buffer.popLong();
    },
    /**
     *
     * @param value
     * @return {!ByteBuffer}
     * @private
     */
    _pushLong: function (value) {
        return this.buffer.putLong(value || 0);
    },
    /**
     *  @param value{string}
     */
    _pushString: function (value) {
        if (value) {
            /**
             * +2 is for length hold place of short
             */
            var length = this.buffer.writeUTF8String(value, this.buffer.writeOffset + 2);
            this._pushShort(length);
            this.buffer.position(this.buffer.writeOffset + length);
        }
        else {
            this._pushShort(0);
        }
    },
    /**
     *  @param value{array}
     */
    _pushArrayLong: function (value) {
        if (value) {
            var len = value.length;
            this._pushShort(len);
            for (var i = 0; i < len; i++) {
                this._pushLong(value[i]);
            }
        }
        else {
            this._pushShort(0);
        }
    },
    /**
     * @return {string|!{string: string, length: number}}
     */
    popString: function () {
        return this.buffer.readUTF8String(this.buffer.popShort());
    },
    /**
     *  @param value{array}
     */
    _pushArrayArray: function (value) {
        if (value) {
            var len = value.length;
            this._pushShort(len);
            for (var i = 0; i < len; i++) {
                if (value[i] instanceof Packet) {
                    this._pushPacket(value[i]);
                }
                else {
                    this._pushBytes(value[i]);
                }
            }
        }
        else {
            this._pushShort(0);
        }
    },
    /**
     *  @param value{array}
     */
    _popArrayArray: function () {
        var len = this.buffer.popShort();
        var vals = [];
        for (var i = 0; i < len; i++) {
            vals[i] = this.popBytes();
        }
        return vals;
    },
    /**
     *  @param value{array}
     */
    _popArrayLong: function () {
        var len = this.buffer.popShort();
        var vals = [];
        for (var i = 0; i < len; i++) {
            vals[i] = this.popLong().value();
        }
        return vals;
    },
    /**
     * @param buffer {ArrayBuffer}
     */
    _pushBytes: function (buffer) {
        if (!buffer || !buffer.byteLength) {
            this.buffer.putShort(0);
        }
        else {
            this.buffer.putShort(buffer.byteLength);
            this.buffer.putBytes(buffer);
        }
    },
    /**
     * @return {ArrayBuffer}
     */
    popBytes: function () {
        return this.buffer.popBytes(this.buffer.popShort());
    },
    popMapOfShortAndInt: function () {
        var result = {};
        var length = this.buffer.popShort();
        for (var i = 0; i < length; i++) {
            var key = this.buffer.popShort();
            var value = this.buffer.popInt();
            result[key] = value;
        }
        return result;
    },
    popMapOfLongAndByte: function () {
        var result = {};
        var length = this.buffer.popShort();
        for (var i = 0; i < length; i++) {
            var key = this.buffer.popLong();
            var value = this.popByte();
            result[key] = value;
        }
        return result;
    },
    popMapOfLongAndShort: function () {
        var result = {};
        var length = this.buffer.popShort();
        for (var i = 0; i < length; i++) {
            var key = this.buffer.popLong();
            var value = this.popShort();
            result[key] = value;
        }
        return result;
    },
    popUItems: function () {
        var invitees = [];
        var len = this.popShort();
        for (var i = 0; i < len; i++) {
            invitees.push(this.popUItem());
        }
        return invitees;
    },
    popUItem: function () {
        var result = {};
        result.uid = this.popLong().value();
        result.appId = this.popShort();
        return result;
    },
    /**
     * @return {ArrayBuffer}
     */
    _pushPacket: function (packet) {
        if (packet) {
            this._pushBytes(packet.getBytes());
        }
    },
    /**
     * 通用的_push接口
     * @param value
     * @option @param type
     */
    push: function (value, type) {
        if (typeof type === 'undefined') {
            if (typeof value === 'string') {
                type = bufferType_1.default.STRING;
            }
            //if given is number,default is int
            else if (typeof value === 'number') {
                type = bufferType_1.default.INT;
            }
            else if (value instanceof Packet) {
                type = bufferType_1.default.PACKET;
            }
            else if (long_1.default.isLong(value)) {
                type = bufferType_1.default.LONG;
            }
            else if (Array.isArray(value)) {
                type = bufferType_1.default.ARRAY_LONG;
            }
        }
        switch (type) {
            case bufferType_1.default.INT:
                this._pushInt(value);
                break;
            case bufferType_1.default.SHORT:
                this._pushShort(value);
                break;
            case bufferType_1.default.LONG:
                this._pushLong(value);
                break;
            case bufferType_1.default.STRING:
                this._pushString(value);
                break;
            case bufferType_1.default.BOOLEAN:
                this._pushBool(value);
                break;
            case bufferType_1.default.BYTE:
                this._pushByte(value);
                break;
            case bufferType_1.default.BYTES:
                this._pushBytes(value);
                break;
            case bufferType_1.default.PACKET:
                this._pushPacket(value);
                break;
            case bufferType_1.default.ARRAY_LONG:
                this._pushArrayLong(value);
                break;
            case bufferType_1.default.ARRAY_ARRAY:
                this._pushArrayArray(value);
                break;
            default:
                throw Error('Unsupported data type: ' + type);
        }
        return this;
    }
};
exports.default = Packet;


//# sourceURL=webpack://MTDX/./src/core/utils/packet.ts?